home *** CD-ROM | disk | FTP | other *** search
/ Explorer - Mosaic & Web / Explorer - Mosaic & Web.iso / helpers / ghostvew / src / gvwpipe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-01  |  6.1 KB  |  215 lines

  1. /* Copyright (C) 1993, 1994, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* gvwpipe.c */
  19. /* pipe support for Windows GSview */
  20. #include "gvwin.h"
  21.  
  22. /* routines to be visible outside this module */
  23. extern void pipeinit();
  24. extern FILE *pipeopen(void);    /* open pipe for first time */
  25. extern void pipeclose(void);    /* finished with pipe, close & delete temp files */
  26. extern void pipereset(void);    /* pipe is empty, do cleanup */
  27. extern void piperequest(void);    /* request from gswin for pipe data */
  28. extern void pipeflush(void);    /* start sending data through pipe */
  29. extern BOOL is_pipe_done(void);    /* true if pipe has just been reset */
  30.  
  31. /* internal to this module */
  32.  
  33. /* imitation pipes using SHAREABLE GLOBAL MEMORY */
  34. #define PIPE_DATASIZE 16380    /* maximum block size */
  35. /* Data is passed to gswin in a global shareable memory block.
  36.  * The global handle is passed in lParam and the byte count
  37.  * is stored in the first word of the global memory block.
  38.  * The maximum number of bytes passed is PIPE_DATASIZE.
  39.  * EOF is signified by count = 0 (hglobal must still be valid)
  40.  */
  41. /* In gsview 1.0, Ghostscript 2.6.1 and earlier, 
  42.  * The global handle was passed in the LOWORD of lParam 
  43.  * and the HIWORD contained the byte count.
  44.  * This was changed in gsview 1.1, Ghostscript 3.0 so that
  45.  * 32 bit handle could be used for Win32  */
  46.  
  47. char pipe_name[MAXSTR];        /* pipe filename */
  48. FILE *pipe_file;        /* pipe file */
  49. fpos_t pipe_wpos;
  50. fpos_t pipe_rpos;
  51. BOOL pipe_empty;
  52. int piperead(char *buf, int size);
  53. char *pipebuf;
  54.  
  55. /* this is called before gswin is started */
  56. /* so we can tell when we get the first piperequest */
  57. void
  58. pipeinit(void)
  59. {
  60.     pipe_empty = FALSE;    /* so we wait for first request */
  61. }
  62.  
  63. FILE *
  64. pipeopen(void)
  65. {
  66.     if (pipe_file != (FILE *)NULL) {
  67.         fclose(pipe_file);
  68.         pipe_file = (FILE *)NULL;
  69.         unlink(pipe_name);
  70.         pipe_name[0] = '\0';
  71.     }
  72.     if ((pipe_file = gp_open_scratch_file(szScratch, pipe_name, "w+b")) == (FILE *)NULL) {
  73.         gserror(IDS_PIPE_EOPEN, NULL, NULL, SOUND_ERROR);
  74.         unlink(pipe_name);
  75.         pipe_name[0] = '\0';
  76.         return (FILE *)NULL;
  77.     }
  78.     pipebuf = malloc(PIPE_DATASIZE);
  79.     pipereset();
  80.     return pipe_file;
  81. }
  82.  
  83. void
  84. pipeclose(void)
  85. {
  86. HGLOBAL hglobal;
  87. LPBYTE lpb;
  88.     if (pipebuf != (char *)NULL) {
  89.         free(pipebuf);
  90.         pipebuf = (char *)NULL;
  91.     }
  92.     if (pipe_file != (FILE *)NULL) {
  93.         fclose(pipe_file);
  94.         pipe_file = (FILE *)NULL;
  95.         unlink(pipe_name);
  96.         pipe_name[0] = '\0';
  97.     }
  98.     if (hwndtext != (HWND)NULL) {
  99. #ifdef GS261
  100.         /* send an EOF (zero length block) */
  101.         hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, 1);
  102.         if (hglobal == (HGLOBAL)NULL) {
  103.             gserror(IDS_PIPE_EMEM, NULL, NULL, SOUND_ERROR);
  104.             return;
  105.         }
  106.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, MAKELPARAM(hglobal,0));
  107. #else
  108.         /* send an EOF (zero length block) */
  109.         hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WORD));
  110.         if (hglobal == (HGLOBAL)NULL) {
  111.             gserror(IDS_PIPE_EMEM, NULL, NULL, SOUND_ERROR);
  112.             return;
  113.         }
  114.         lpb = GlobalLock(hglobal);
  115.         *((WORD FAR *)lpb) = 0;
  116.         GlobalUnlock(hglobal);
  117.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, (LPARAM)hglobal);
  118. #endif
  119.     }
  120.     pipe_empty = TRUE;
  121. }
  122.  
  123. /* rpos and wpos are now empty so reset the file */
  124. void
  125. pipereset(void)
  126. {
  127.     if ( (pipe_file == (FILE *)NULL) || (pipe_name[0] == '\0') )
  128.         return;
  129.     if ((pipe_file = freopen(pipe_name, "w+b", pipe_file)) == (FILE *)NULL) {
  130.         gserror(IDS_PIPE_EOPEN, NULL, NULL, SOUND_ERROR);
  131.         unlink(pipe_name);
  132.         pipe_name[0] = '\0';
  133.         return;
  134.     }
  135.     fgetpos(pipe_file, &pipe_rpos);
  136.     fgetpos(pipe_file, &pipe_wpos);
  137.     pipe_empty = TRUE;
  138.     info_wait(FALSE);
  139. }
  140.  
  141. /* give another block of data to gswin */
  142. /* called from WndImgProc */
  143. void
  144. piperequest(void)
  145. {
  146. HGLOBAL hglobal;
  147. LPBYTE lpb;
  148. UINT count;
  149.     if (pipe_file == (FILE *)NULL) {
  150.         pipe_empty = TRUE;
  151.         return;
  152.     }
  153.  
  154.     count = piperead(pipebuf, PIPE_DATASIZE);
  155.     if (count==0)
  156.         return;
  157.  
  158.     hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, PIPE_DATASIZE + sizeof(WORD));
  159.     if (hglobal == (HGLOBAL)NULL) {
  160.         gserror(IDS_PIPE_EMEM, NULL, NULL, SOUND_ERROR);
  161.         return;
  162.     }
  163. #ifdef GS261
  164.     lpb = GlobalLock(hglobal);
  165.     _fmemcpy(lpb, pipebuf, count);
  166.     GlobalUnlock(hglobal);
  167.     /* we may be processing SendMessage so use PostMessage to avoid lockups */
  168.     PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, MAKELPARAM(hglobal,count));
  169. #else
  170.     lpb = GlobalLock(hglobal);
  171.     *((WORD FAR *)lpb) = (WORD)count;
  172.     _fmemcpy(lpb+sizeof(WORD), pipebuf, count);
  173.     GlobalUnlock(hglobal);
  174.     /* we may be processing SendMessage so use PostMessage to avoid lockups */
  175.     PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, (LPARAM)hglobal);
  176. #endif
  177. }
  178.  
  179. /* write pipe_file to pipe */
  180. void
  181. pipeflush(void)
  182. {
  183.     if (pipe_empty) {
  184.         pipe_empty = FALSE;
  185.         piperequest();    /* repeat the request */
  186.     }
  187.     info_wait(TRUE);
  188. }
  189.  
  190. /* true  if pipereset was last called */
  191. /* false if pipeflush was last called */
  192. int
  193. is_pipe_done(void)
  194. {
  195.     return pipe_empty;
  196. }
  197.  
  198. /* read a block from pipe */
  199. /* return count of characters read */
  200. /* reset pipe if empty */
  201. int
  202. piperead(char *buf, int size)
  203. {
  204. int rcount;
  205.     fflush(pipe_file);
  206.     fgetpos(pipe_file,&pipe_wpos);
  207.     fsetpos(pipe_file,&pipe_rpos);
  208.     rcount = fread(buf, 1, size, pipe_file);
  209.     fgetpos(pipe_file,&pipe_rpos);
  210.     fsetpos(pipe_file,&pipe_wpos);
  211.     if (rcount == 0)
  212.        pipereset();
  213.     return rcount;
  214. }
  215.